﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using WooCoo.Tools;

namespace WooCoo.DataPortal.Client
{
    /// <summary>查询组件,查询表达式转换为本对象.</summary>
    public class QueryComponents
    {
        /// <summary>用处投影的查询项.</summary>
        private const string SelectQueryOption = "$select=";
        /// <summary>Select查询项，出现在查询字符串起始.</summary>
        private const string SelectQueryOptionWithQuestionMark = "?$select=";
        /// <summary>Select查询项，出现在查询字符串中间.</summary>
        private const string SelectQueryOptionWithAmpersand = "&$select=";
        private readonly Type lastSegmentType;
        /// <summary>记录表达式标准化时源-标准化后的表达式关系字典.</summary>
        private readonly Dictionary<Expression, Expression> normalizerRewrites;
        /// <summary>投影表达式</summary>
        private readonly LambdaExpression projection;
        private readonly string httpMethod;
        private readonly List<UriOperationParameter> uriOperationParameters;
        private readonly List<BodyOperationParameter> bodyOperationParameters;
        private readonly bool? singleResult;
        /// <summary> URI for query </summary>
        private Uri uri;
        private Version version;
        public Uri Uri
        {
            get
            {
                return this.uri;
            }
            set
            {
                this.uri = value;
            }
        }
        public Dictionary<Expression, Expression> NormalizerRewrites
        {
            get
            {
                return this.normalizerRewrites;
            }
        }

        public LambdaExpression Projection
        {
            get
            {
                return this.projection;
            }
        }
        public Type LastSegmentType
        {
            get
            {
                return this.lastSegmentType;
            }
        }
        public Version Version
        {
            get
            {
                return this.version;
            }
        }
        public string HttpMethod
        {
            get
            {
                return this.httpMethod;
            }
        }
        /// <summary>与服务功能或服务操作关联的URI的操作参数列表</summary>
        internal List<UriOperationParameter> UriOperationParameters
        {
            get
            {
                return this.uriOperationParameters;
            }
        }
        /// <summary>与服务端Action相关的Body操作参数列表.</summary>
        internal List<BodyOperationParameter> BodyOperationParameters
        {
            get
            {
                return this.bodyOperationParameters;
            }
        }
        public bool? SingleResult
        {
            get
            {
                return this.singleResult;
            }
        }
        /// <summary>
        /// 判断URI中是否包含select查询项.
        /// </summary>
        internal bool HasSelectQueryOption
        {
            get
            {
                return this.Uri != null && QueryComponents.ContainsSelectQueryOption(UriHelper.UriToString(this.Uri));
            }
        }
        /// <summary>
        ///  用于HttpGet的查询组件构造方法.
        /// </summary>
        /// <param name="uri">URI for the query</param>
        /// <param name="version">Version for the query</param>
        /// <param name="lastSegmentType">查询类型</param>
        /// <param name="projection">投影的LambdaExpression</param>
        /// <param name="normalizerRewrites">Records the generated-to-source rewrites created (possibly null).</param>
        public QueryComponents(Uri uri, Version version, Type lastSegmentType, LambdaExpression projection, Dictionary<Expression, Expression> normalizerRewrites)
        {
            this.projection = projection;
            this.normalizerRewrites = normalizerRewrites;
            this.lastSegmentType = lastSegmentType;
            this.uri = uri;
            this.version = version;
            this.httpMethod = "GET";
        }
        /// <summary>
        ///  用于HttpGet的查询组件构造方法.
        /// </summary>
        /// <param name="uri">URI for the query</param>
        /// <param name="version">Version for the query</param>
        /// <param name="lastSegmentType">查询类型</param>
        /// <param name="projection">投影的LambdaExpression</param>
        /// <param name="normalizerRewrites">Records the generated-to-source rewrites created (possibly null).</param>
        /// <param name="bodyOperationParameters">与服务端Action相关的Body操作参数列表.</param>
        /// <param name="uriOperationParameters">与服务功能或服务操作关联的URI的操作参数.</param> 
        public QueryComponents(Uri uri, Version version, Type lastSegmentType, LambdaExpression projection, Dictionary<Expression, Expression> normalizerRewrites, string httpMethod, bool? singleResult, List<BodyOperationParameter> bodyOperationParameters, List<UriOperationParameter> uriOperationParameters)
        {
            this.projection = projection;
            this.normalizerRewrites = normalizerRewrites;
            this.lastSegmentType = lastSegmentType;
            this.uri = uri;
            this.version = version;
            this.httpMethod = httpMethod;
            this.uriOperationParameters = uriOperationParameters;
            this.bodyOperationParameters = bodyOperationParameters;
            this.singleResult = singleResult;
        }

        private static bool ContainsSelectQueryOption(string queryString)
        {
            return queryString.Contains("?$select=") || queryString.Contains("&$select=");
        }
    }
}
